<template>
    <div class="home container" id="fullscreen-container" ref="fullscreen">
      <slot name="card"></slot>
      <slot name="search"></slot>
      <div class="controlbox">
        <el-tooltip class="item" effect="dark" content="点击进行定位" placement="left-start">
          <i class="el-icon-map-location" style="color:blue;margin-top: 10px;" @click="drawImage"></i>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="点击开始绘制围栏" placement="left-start">
          <i class="el-icon-share" style="color:blue;margin-top: 10px;" @click="drawPolygon"></i>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="停止绘制围栏" placement="left-start">
          <i class="el-icon-video-pause" style="color:red;margin-top: 10px;" @click="stopPolygon"></i>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="清除围栏" placement="left-start">
          <i class="el-icon-delete" style="color:red;margin-top: 10px;" @click="clearDraw"></i>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="开始修改图层" placement="left-start">
          <i class="el-icon-edit" style="color:blue;margin-top: 10px;" @click="startModify('json')"></i>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="开始修改围栏" placement="left-start">
          <i class="el-icon-edit" style="color:blue;margin-top: 10px;" @click="startModify('polygon')"></i>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="停止修改" placement="left-start">
          <i class="el-icon-video-pause" style="color:yellowgreen;margin-top: 10px;" @click="endModify"></i>
        </el-tooltip>
      </div>
 
      <div id="map" class="map-container" :style="{'width':mapWidth,'height':mapHeight}"></div>
      <el-tooltip ref="elTooltip" :append-to-body="false" class="item" effect="light" placement="left">
			<div slot="content">
				<div class="mapbox">
					<li @click="mapChangeType('1')" :class="mapModel.active[0]?'activeStyle':''">
            <img src="../assets/image/dixing.jpg" width="100px" height="50px">
						<div class="on">地形地图</div>
					</li>
					<li @click="mapChangeType('2')" :class="mapModel.active[1]?'activeStyle':''">
            <img src="../assets/image/yingxiang.jpg" width="100px" height="50px">
						<div class="on">影像地图</div>
					</li>
				</div>
			</div>
			<div class="map0"></div>
		</el-tooltip>
    </div>
  </template>
<script lang="ts">
import { Map, View ,Feature} from "ol";
import { FullScreen } from "ol/control";
import { Vector as VectorSource } from "ol/source";
import { Tile as TileLayer} from "ol/layer";
import { Vector as VectorLayer } from "ol/layer";
import { Style, Fill, Stroke} from "ol/style";
import {Point } from "ol/geom";
import CircleStyle from 'ol/style/Circle'

import { XYZ} from "ol/source";
import { Component, Vue,Prop ,Watch, Emit,Ref} from 'vue-property-decorator';
import GeoJSON from "ol/format/GeoJSON";
import Draw from 'ol/interaction/Draw';
import MultiPoint from 'ol/geom/MultiPoint';
import { getArea } from 'ol/sphere';
import { Polygon } from 'ol/geom';
import MeasureTool from '../assets/js/measure.js';
import Modify from 'ol/interaction/Modify'
import {uploadJsonAsFile} from '@/utils/axios';

@Component({})
export default class RegionMap extends Vue {
    @Ref('fullscreen') private fullscreen!:any;
    @Ref('elTooltip') private elTooltip!:any;
    mapModel:any={
        drawGeoJson:null,
        openMap: null,
        resourceUrl: '/resources/file/',
        mapLanLot:[111.670801 ,40.818311],
        geoJsonLayer:null,
        geoJsonSource: null,
        positionCoord:null,
        originLayer1:null,
        originLayer2:null,
        active:[true,false],
        polygonArea: 0,
        modify:null,
        positionSource: new VectorSource({
          // projection: 'EPSG:4326',
					wrapX: false
				}),
        polygonSource:new VectorSource({
          // projection: 'EPSG:4326',
					wrapX: false
				}),
        //点标记
        pointMaker:null,
        checkList:[],
        draw:null,
    };
    @Prop() private mapWidth!:string;
    @Prop() private mapHeight!:string;
    @Prop() private vectorId!:string;
    @Prop() private position!:string;
    @Prop() private polygon!:string;


    initMap() {

      let polygonLayer = new VectorLayer({
					source: this.mapModel.polygonSource,
					style: [
						new Style({
							fill: new Fill({
								color: 'transparent'
							}),
							stroke: new Stroke({
								width: 2,
								color: "blue",
							}),
						}),
						new Style({
							image: new CircleStyle({
								radius: 5,
								fill: new Fill({
									color: 'red'
								}),
								stroke: new Stroke({
									color: 'orange',
									width: 2
								})
							}),
							geometry: function(feature:any) {
								let coordinates = feature.getGeometry().getCoordinates()[0];
								return new MultiPoint(coordinates);
							}
						}),
					]
				});
        this.mapModel.originLayer1 = new TileLayer({
              visible:true,
              source: new XYZ({
                url: "https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}",
              }),
        });
        this.mapModel.originLayer2 = new TileLayer({
              visible:false,
              source: new XYZ({
               // url: "https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=6&x={x}&y={y}&z={z}",
                url:'https://gx.jdfktech.com:18279/yjearth4.0/data/mbt/d2a3af49472423af91e5999f83b6e705/{z}/{x}/{y}.png'
                
              }),
        });
        this.mapModel.openMap = new Map({
          target: "map",
          controls:[new FullScreen({
            source:document.getElementById('fullscreen-container') as any
          })],
          layers: [
            this.mapModel.originLayer1,
            this.mapModel.originLayer2,
            polygonLayer
          ],
          view: new View({
            // 将呼市作为地图中心
            center: [111.670801 ,40.818311],
            zoom: 8,
            projection: "EPSG:4326",
          }),
        });
    }

    get baseUrl(){

      return `${process.env.VUE_APP_DISK}${ process.env.VUE_APP_BASE_API}${this.mapModel.resourceUrl}`;
    }

    singleclick() {
      this.mapModel.openMap.on("singleclick", (e) => {
          // 判断是否点击在点上
          this.backMessage(e.coordinate[0] + ',' + e.coordinate[1]);
      });
    }

    getarea0(x) {
				this.clearMeasure()
				MeasureTool.measure(this.mapModel.openMap, x, true);
		}

    getlength0(x) {
				this.clearMeasure()
				MeasureTool.measure(this.mapModel.openMap, x, true);
			}

    clearMeasure() { //清除图层，中间参数为空
      MeasureTool.measure(this.mapModel.openMap, "", false);
    }

    getPolygon(){
      if(this.mapModel.polygonSource){
        const ft = this.mapModel.polygonSource.getFeatures()[0];
        if(ft && ft.getGeometry()){
          return JSON.stringify(ft.getGeometry().getCoordinates());
        }
        return "";
      }
      return "";
    }

    getGeoFile(){
      return  this.mapModel.drawGeoJson;
    }

    outputJson() {
      let features = this.mapModel.geoJsonSource.getFeatures();
      let jsonObj = new GeoJSON().writeFeatures(features);
    
      uploadJsonAsFile(jsonObj).then((res:any) =>{
        this.mapModel.drawGeoJson = res.data.id;
      })
    }

  

    mapChangeType(x:any) {
				switch (x) {
					case '1':
            console.log(this.mapModel.originLayer1)
						this.mapModel.originLayer1.setVisible(true);
						this.mapModel.originLayer2.setVisible(false);
						this.mapModel.active=[true,false]
						break;
					case '2':
            this.mapModel.originLayer1.setVisible(false);
						this.mapModel.originLayer2.setVisible(true);
						this.mapModel.active=[false,true]
						break;
				}
		}

    startModify(type:any) {

        switch(type){
          case 'json':
            this.mapModel.modify = new Modify({
              source: this.mapModel.geoJsonSource,
            });
            break;
            case 'polygon':
              this.mapModel.modify = new Modify({
                source: this.mapModel.polygonSource,
              });
            break;
        }

				this.mapModel.openMap.addInteraction(this.mapModel.modify);
		}

		endModify() {
				if (this.mapModel.modify !== null) {
					this.mapModel.openMap.removeInteraction(this.mapModel.modify);
        }
        this.outputJson();
		}

    loadGeoJson(newValue){
        const val = newValue || this.vectorId;
        if(val){
          this.mapModel.geoJsonSource?.clear();
          this.mapModel.geoJsonSource = new VectorSource({
                  url:  this.baseUrl + val,
                  format: new GeoJSON()
          });

          this.mapModel.geoJsonLayer = new VectorLayer({source:this.mapModel.geoJsonSource});
          if(this.mapModel.geoJsonLayer && this.mapModel.geoJsonSource){
              this.mapModel.openMap.addLayer(this.mapModel.geoJsonLayer);
             // this.mapModel.openMap.getView().fit(this.mapModel.geoJsonSource.getExtent());
          }
        }

        let pointLayer = new VectorLayer({
					source: this.mapModel.positionSource,
					style: new Style({
						fill: new Fill({
							color: "orange"
						}),
						stroke: new Stroke({
							width: 2,
							color: "darkgreen",
						}),
						image: new CircleStyle({ //点样式
							radius: 5,
							fill: new Fill({
								color: 'red'
							})
						}),
					})
				});
        this.mapModel.openMap.addLayer(pointLayer);
  }

  drawImage() {
     this.mapModel.positionSource.clear()
    // 停止上一次的绘制，没有此代码会出现重叠
    this.removeMaker();
    if (this.mapModel.draw !== null) {
      this.mapModel.openMap.removeInteraction(this.mapModel.draw)
    }
    this.mapModel.draw = new Draw({
      source: this.mapModel.positionSource,
      type: 'Point',
    })
    this.mapModel.openMap.addInteraction(this.mapModel.draw)
    let coord: any;
    this.mapModel.draw.on('drawend', (e) => {
      this.mapModel.openMap.removeInteraction(this.mapModel.draw)
      coord = e.feature.getGeometry().getCoordinates() //获取最后点坐标
      let flag = false;
      if(this.mapModel.geoJsonSource){
        let geoJsonFeatures = this.mapModel.geoJsonSource.getFeatures();
        for (let ft of geoJsonFeatures) {
          let polygonGeometry = ft.getGeometry();
          //判断是否在Geometry内
          flag = polygonGeometry.intersectsCoordinate(coord);
          if (flag) {
            break;
          }
        }
      }
      if(this.mapModel.polygonSource){
        let polygonFeatures = this.mapModel.polygonSource.getFeatures();
        for (let ft of polygonFeatures) {
          let polygonGeometry = ft.getGeometry();
          //判断是否在Geometry内
          flag = polygonGeometry.intersectsCoordinate(coord);
          if (flag) {
            break;
          }
        }
      }

        if (flag) {
          this.$message({type: 'success',duration: 1000,message: '位置正确' + coord});
          this.mapModel.positionCoord = coord;
          this.backMessage(coord[0] + ',' + coord[1]);
          this.setMarker(coord);
        } else {
          this.$message({type: 'error',duration: 1000,message: '位置不正确，不在区划内'})
        }
      });
    }


    removeMaker(){
      if(this.mapModel.pointMaker){
        this.mapModel.openMap.removeLayer(this.mapModel.pointMaker);
        this.mapModel.pointMaker = null;
      }
    }

    drawPolygon() {
      this.mapModel.polygonArea  = 0;
      this.mapModel.polygonSource.clear();
      if (this.mapModel.draw !== null) {
        this.mapModel.openMap.removeInteraction(this.mapModel.draw);
      }
      this.mapModel.draw = new Draw({
        source: this.mapModel.polygonSource,
        type: 'Polygon',
      })
      this.mapModel.openMap.addInteraction(this.mapModel.draw);

      this.mapModel.polygonSource.forEachFeature(feature => {
        // 获取特征的几何形状
        const geometry = feature.getGeometry();
        // 如果特征是多边形
        if (geometry instanceof Polygon) {
          // 计算面积
          const area = getArea(geometry);
          this.mapModel.polygonArea += area;
        }
      });
    }

    clearDraw(){
				this.mapModel.polygonSource.clear()
		}

    stopPolygon(){
      if(this.mapModel.draw != null){
        this.mapModel.openMap.removeInteraction(this.mapModel.draw);
      }
     // this.getPolygon();
    }

    setMarker(point) {
        this.mapModel.pointMaker = new VectorLayer({
            source: new VectorSource({
            features: [new Feature({
              geometry: new Point(point),
              style: new Style({
                image: new CircleStyle({
                  radius: 15,
                  stroke: new Stroke({
                      color: "#fff",
                  }),
                  fill: new Fill({
                      color: "#3399CC",
                  }),
                }),
              })
            })],
            }),
        });
        this.mapModel.openMap.addLayer(this.mapModel.pointMaker);
        this.positionChangeHandler();
    }

    @Emit('positionChange')
    positionChangeHandler(){
      return this.mapModel.positionCoord;
    }

    @Emit('currentPosition')
    backMessage(position){
        return position;
    }
    mounted() {
      this.initMap();
      this.singleclick();
      this.fullscreen.appendChild(this.elTooltip.popperVM.$el)
    }
    @Watch('vectorId')
    updateVectore(val:any){
      if(this.mapModel.geoJsonLayer){
          this.mapModel.geoJsonSource = null;
          this.mapModel.openMap.removeLayer(this.mapModel.geoJsonLayer);
      }
      if(val){

          this.loadGeoJson(val);
      }
    }

    startDrawGeoSource(){
      if(this.mapModel.geoJsonSource){
        let geoJsonFeatures = this.mapModel.geoJsonSource.getFeatures();
        this.mapModel.polygonSource.addFeature(geoJsonFeatures);
      }
    }

    @Watch('polygon')
    updatePolygon(val:any){
      this.mapModel.polygonSource && this.mapModel.polygonSource.clear();
      if(this.mapModel.polygonSource && val){
        var feature = new Feature({
            geometry: new Polygon(JSON.parse(val))
        });

        this.mapModel.polygonSource.addFeature(feature);
      }
    }

    @Watch('position')
    updatePosition(val:any){
        if(val){
            this.mapModel.openMap.getView().animate({
            center: val, // 新的中心坐标
            zoom: 16,        // 新的缩放级别
            duration: 3000   // 动画持续时间（毫秒）
        });
          this.setMarker(val);
      }
    }
  }
  </script>
  <style scoped>
  .map0 {
    opacity:0.8;
		width: 24px;
		height: 24px;
		background: url(../assets/image/tooltip.png) center center no-repeat;
		background-size: 16px 16px;
		position: absolute;
		right: 60px;
		top: 10px;
		z-index: 200;
		cursor: pointer;
	}
  .map1 {
    opacity:0.5;
		width: 250px;
		height: 40px;
		background: #000 center center no-repeat;
		position: absolute;
		right: 0px;
		top: 0px;
		z-index: 200;
		cursor: pointer;
	}

	.mapbox {
		width: 220px;
		height: 60px;
		display: flex;
		flex-wrap: nowrap;
		justify-content: space-between;
	}

	.mapbox li {
		width: 100px;
		height: 50px;
		margin: 5px 0;
		display: block;
		position: relative;
		cursor: pointer;
	}

	.mapbox li .on {
		height: 16px;
		width: 100px;
		background-color: rgba(0, 0, 0, 0.3);
		color: #fff;
		font-size: 12px;
		position: absolute;
		bottom: 0;
		left: 0;
		display: none;
		text-align: center;
	}
  .mapbox li:hover .on{ display: block;}
	.activeStyle {
		width: 100px;
		height: 50px;
		border: 1px solid #f00;
	}
  .container {
		border: 1px solid #42B983;
		position: relative;
    min-width: 100vh;
	}

  .controlbox {
    opacity:0.8;
		position: absolute;
		z-index: 10000;
		bottom: 200px;
		width: 18px;
		padding: 5px 7px;
		height: 200px;
		right: 20px;
		border: 1px solid #ccc;
		border-radius: 4px;
		cursor: pointer;
		display: flex;
		align-content: space-between;
		flex-direction: column;
		background-color: #fff;
	}

	.getlength0 {
		width: 18px;
		height: 30px;
		background: url(../assets/image/getnlength.png) center center no-repeat;
		background-size: 16px 16px;
	}

	.getarea0 {
		width: 18px;
		height: 30px;
		background: url(../assets/image/getarea.png) center center no-repeat;
		background-size: 16px 16px;
	}


</style>
